/**
 * API 服务模块
 * 封装所有与后端API的交互
 */

// API 响应接口定义
export interface ApiResponse<T = any> {
  success: boolean
  data?: T
  message?: string
  error?: string
}

// 用户信息接口
export interface User {
  id: number
  username: string
  email?: string
  created_at: string
  updated_at: string
}

// 登录响应接口
export interface LoginResponse {
  user: User
  access: string
  refresh: string
}

// 注册请求接口
export interface RegisterRequest {
  username: string
  password: string
  email?: string
}

// 登录请求接口
export interface LoginRequest {
  email: string
  password: string
}

// 修改密码请求接口
export interface ChangePasswordRequest {
  old_password: string
  new_password: string
}

// Token刷新响应接口
export interface RefreshTokenResponse {
  access: string
  refresh: string
}

// 共享链接请求接口
export interface ShareLinkRequest {
  resourceType: 'folder' | 'note'
  resourceId: number
  password?: string
  expiresAt?: string
}

// 共享链接响应接口
export interface ShareLinkResponse {
  shareLink: string
  shareId: string
  password?: string
  expiresAt?: string
}

// 同步请求接口
export interface SyncRequest {
  categories: any[]
  notes: any[]
  lastSyncTime?: string
  pendingChanges?: any[] // 待同步更改列表
}

// 同步响应接口
export interface SyncResponse {
  session_id: string
  status: string
  sync_time: string
  items_uploaded: number
  items_downloaded: number
  conflicts_detected: number
  notes: any[]
  categories: any[]
  tags: any[]
  conflicts: any[]
}

/**
 * API 客户端类
 */
class ApiClient {
  private baseUrl: string = ''
  private accessToken: string = ''

  /**
   * 设置服务器基础URL
   * @param url 服务器地址
   */
  setBaseUrl(url: string): void {
    this.baseUrl = url.endsWith('/') ? url.slice(0, -1) : url
  }

  /**
   * 设置访问令牌
   * @param token JWT访问令牌
   */
  setAccessToken(token: string): void {
    this.accessToken = token
  }

  /**
   * 获取访问令牌
   * @returns JWT访问令牌
   */
  getAccessToken(): string {
    return this.accessToken
  }

  /**
   * 尝试刷新访问令牌
   * @returns Promise<boolean> 是否刷新成功
   */
  private async attemptTokenRefresh(): Promise<boolean> {
    try {
      // 动态导入auth模块以避免循环依赖
      const { refreshAccessToken } = await import('./auth')
      return await refreshAccessToken()
    } catch (error) {
      console.error('Token刷新失败:', error)
      return false
    }
  }

  /**
   * 处理Token过期，自动登出并显示重新登录提示
   */
  private async handleTokenExpired(): Promise<void> {
    try {
      // 动态导入相关模块以避免循环依赖
      const { clearAuthState } = await import('./auth')
      const { showError } = await import('./notification')
      
      // 清除认证状态
      clearAuthState()
      
      // 显示错误通知
      showError('登录已过期，请重新登录', 'Token过期', 0) // 0表示不自动消失
      
      console.log('用户已自动登出，需要重新登录')
    } catch (error) {
      console.error('处理Token过期时出错:', error)
    }
  }

  /**
   * 发送HTTP请求
   * @param endpoint API端点
   * @param options 请求选项
   * @returns Promise<ApiResponse>
   */
  private async request<T>(
    endpoint: string,
    options: RequestInit = {}
  ): Promise<ApiResponse<T>> {
    const url = `${this.baseUrl}/api/v1${endpoint}`
    
    const defaultHeaders: Record<string, string> = {
      'Content-Type': 'application/json',
    }

    // 如果有访问令牌，添加到请求头
    if (this.accessToken) {
      defaultHeaders['Authorization'] = `Bearer ${this.accessToken}`
      console.log('API请求包含Authorization头:', `Bearer ${this.accessToken.substring(0, 20)}...`)
    } else {
      console.warn('API请求没有访问令牌:', endpoint)
    }

    const config: RequestInit = {
      ...options,
      headers: {
        ...defaultHeaders,
        ...options.headers,
      },
    }

    try {
      const response = await fetch(url, config)
      const data = await response.json()

      // 如果是401错误且有访问令牌，尝试刷新Token
      if (response.status === 401 && this.accessToken) {
        console.log('收到401响应，尝试刷新Token...')
        const refreshed = await this.attemptTokenRefresh()
        if (refreshed) {
          // Token刷新成功，重试请求
          const retryHeaders = { ...config.headers }
          if (this.accessToken) {
            retryHeaders['Authorization'] = `Bearer ${this.accessToken}`
          }
          const retryConfig = { ...config, headers: retryHeaders }
          const retryResponse = await fetch(url, retryConfig)
          const retryData = await retryResponse.json()
          
          if (!retryResponse.ok) {
            return {
              success: false,
              error: retryData.message || retryData.error || `HTTP ${retryResponse.status}`,
              data: retryData
            }
          }
          
          return {
            success: true,
            data: retryData,
            message: retryData.message
          }
        } else {
          // Token刷新失败，自动登出并提示重新登录
          console.log('Token刷新失败，自动登出')
          await this.handleTokenExpired()
          return {
            success: false,
            error: 'Token已过期，请重新登录',
            data: null
          }
        }
      }

      if (!response.ok) {
        return {
          success: false,
          error: data.message || data.error || `HTTP ${response.status}`,
          data: data
        }
      }

      return {
        success: true,
        data: data,
        message: data.message
      }
    } catch (error) {
      console.error('API请求失败:', error)
      return {
        success: false,
        error: error instanceof Error ? error.message : '网络请求失败'
      }
    }
  }

  /**
   * GET 请求
   * @param endpoint API端点
   * @returns Promise<ApiResponse>
   */
  async get<T>(endpoint: string): Promise<ApiResponse<T>> {
    return this.request<T>(endpoint, { method: 'GET' })
  }

  /**
   * POST 请求
   * @param endpoint API端点
   * @param data 请求数据
   * @returns Promise<ApiResponse>
   */
  async post<T>(endpoint: string, data?: any): Promise<ApiResponse<T>> {
    return this.request<T>(endpoint, {
      method: 'POST',
      body: data ? JSON.stringify(data) : undefined,
    })
  }

  /**
   * PUT 请求
   * @param endpoint API端点
   * @param data 请求数据
   * @returns Promise<ApiResponse>
   */
  async put<T>(endpoint: string, data?: any): Promise<ApiResponse<T>> {
    return this.request<T>(endpoint, {
      method: 'PUT',
      body: data ? JSON.stringify(data) : undefined,
    })
  }

  /**
   * PATCH 请求
   * @param endpoint API端点
   * @param data 请求数据
   */
  async patch<T>(endpoint: string, data?: any): Promise<ApiResponse<T>> {
    return this.request<T>(endpoint, {
      method: 'PATCH',
      body: data ? JSON.stringify(data) : undefined
    })
  }

  /**
   * DELETE 请求
   * @param endpoint API端点
   */
  async delete<T>(endpoint: string): Promise<ApiResponse<T>> {
    return this.request<T>(endpoint, { method: 'DELETE' })
  }

  // ==================== 认证相关API ====================

  /**
   * 用户登录
   * @param credentials 登录凭据
   * @returns Promise<ApiResponse<LoginResponse>>
   */
  async login(credentials: LoginRequest): Promise<ApiResponse<LoginResponse>> {
    return this.post<LoginResponse>('/auth/login/', credentials)
  }

  /**
   * 用户注册
   * @param userData 注册数据
   * @returns Promise<ApiResponse<User>>
   */
  async register(userData: RegisterRequest): Promise<ApiResponse<User>> {
    return this.post<User>('/auth/register/', userData)
  }

  /**
   * 刷新访问令牌
   * @param refreshToken 刷新令牌
   * @returns Promise<ApiResponse<RefreshTokenResponse>>
   */
  async refreshToken(refreshToken: string): Promise<ApiResponse<RefreshTokenResponse>> {
    return this.post<RefreshTokenResponse>('/auth/refresh/', {
      refresh: refreshToken
    })
  }

  /**
   * 用户登出
   * @returns Promise<ApiResponse>
   */
  async logout(): Promise<ApiResponse> {
    return this.post('/auth/logout/')
  }

  /**
   * 获取当前用户信息
   * @returns Promise<ApiResponse<User>>
   */
  async getCurrentUser(): Promise<ApiResponse<User>> {
    return this.get<User>('/auth/user/')
  }

  /**
   * 修改密码
   * @param passwordData 密码数据
   * @returns Promise<ApiResponse>
   */
  async changePassword(passwordData: ChangePasswordRequest): Promise<ApiResponse> {
    return this.put('/auth/change-password/', passwordData)
  }

  // ==================== 笔记相关API ====================

  /**
   * 获取笔记列表
   * @param params 查询参数
   * @returns Promise<ApiResponse>
   */
  async getNotes(params?: Record<string, any>): Promise<ApiResponse> {
    const queryString = params ? '?' + new URLSearchParams(params).toString() : ''
    return this.get(`/notes/${queryString}`)
  }

  /**
   * 创建笔记
   * @param noteData 笔记数据
   * @returns Promise<ApiResponse>
   */
  async createNote(noteData: any): Promise<ApiResponse> {
    return this.post('/notes/', noteData)
  }

  /**
   * 更新笔记
   * @param noteId 笔记ID
   * @param noteData 笔记数据
   * @returns Promise<ApiResponse>
   */
  async updateNote(noteId: number, noteData: any): Promise<ApiResponse> {
    return this.put(`/notes/${noteId}/`, noteData)
  }

  /**
   * 删除笔记
   * @param noteId 笔记ID
   * @returns Promise<ApiResponse>
   */
  async deleteNote(noteId: number): Promise<ApiResponse> {
    return this.delete(`/notes/${noteId}/`)
  }

  // ==================== 分类相关API ====================

  /**
   * 获取分类列表
   * @returns Promise<ApiResponse>
   */
  async getCategories(): Promise<ApiResponse> {
    return this.get('/categories/')
  }

  /**
   * 创建分类
   * @param categoryData 分类数据
   * @returns Promise<ApiResponse>
   */
  async createCategory(categoryData: any): Promise<ApiResponse> {
    return this.post('/categories/', categoryData)
  }

  // ==================== 共享链接相关API ====================

  /**
   * 创建共享链接
   * @param shareData 共享数据
   * @returns Promise<ApiResponse<ShareLinkResponse>>
   */
  async createShareLink(shareData: ShareLinkRequest): Promise<ApiResponse<ShareLinkResponse>> {
    return this.post<ShareLinkResponse>('/sharing/create/', shareData)
  }

  /**
   * 获取共享内容
   * @param shareId 共享ID
   * @param password 密码（可选）
   * @returns Promise<ApiResponse>
   */
  async getSharedContent(shareId: string, password?: string): Promise<ApiResponse> {
    const data = password ? { password } : {}
    return this.post(`/sharing/${shareId}/`, data)
  }

  /**
   * 删除共享链接
   * @param shareId 共享ID
   * @returns Promise<ApiResponse>
   */
  async deleteShareLink(shareId: string): Promise<ApiResponse> {
    return this.delete(`/sharing/${shareId}/`)
  }

  // ==================== 数据同步相关API ====================

  /**
   * 同步数据到服务器
   * @param syncData 同步数据
   * @returns Promise<ApiResponse<SyncResponse>>
   */
  async syncData(syncData: SyncRequest): Promise<ApiResponse<SyncResponse>> {
    return this.post<SyncResponse>('/sync/sync/', syncData)
  }

  /**
   * 获取服务器数据
   * @param lastSyncTime 最后同步时间
   * @returns Promise<ApiResponse<SyncResponse>>
   */
  async getServerData(lastSyncTime?: string): Promise<ApiResponse<SyncResponse>> {
    const params = lastSyncTime ? `?lastSyncTime=${encodeURIComponent(lastSyncTime)}` : ''
    return this.get<SyncResponse>(`/sync/${params}`)
  }

  /**
   * 上传文件夹数据
   * @param folders 文件夹数据
   * @returns Promise<ApiResponse>
   */
  async uploadFolders(folders: any[]): Promise<ApiResponse> {
    return this.post('/sync/folders/', { folders })
  }

  /**
   * 上传笔记数据
   * @param notes 笔记数据
   * @returns Promise<ApiResponse>
   */
  async uploadNotes(notes: any[]): Promise<ApiResponse> {
    return this.post('/sync/notes/', { notes })
  }
}

// 创建全局API客户端实例
export const apiClient = new ApiClient()

// 导出API客户端类
export { ApiClient }

/**
 * 初始化API客户端
 * @param serverUrl 服务器地址
 * @param accessToken 访问令牌（可选）
 */
export function initializeApi(serverUrl: string, accessToken?: string): void {
  apiClient.setBaseUrl(serverUrl)
  if (accessToken) {
    apiClient.setAccessToken(accessToken)
  }
}

/**
 * 检查服务器连接
 * @param serverUrl 服务器地址
 * @returns Promise<boolean>
 */
export async function checkServerConnection(serverUrl: string): Promise<boolean> {
  try {
    const url = serverUrl.endsWith('/') ? serverUrl.slice(0, -1) : serverUrl
    const response = await fetch(`${url}/api/v1/health/`, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    })
    return response.ok
  } catch (error) {
    console.error('服务器连接检查失败:', error)
    return false
  }
}